package com.credithc.signature.manager.controller;

import com.credithc.baseserv.core.codes.CoreCodes;
import com.credithc.baseserv.core.exception.BsException;
import com.credithc.baseserv.core.message.Message;
import com.credithc.baseserv.core.message.MessageFactory;
import com.credithc.baseserv.pageHelper.PageInfo;
import com.credithc.signature.common.constant.ManagerConstant;
import com.credithc.signature.common.mapper.FddSealInfoMapper;
import com.credithc.signature.common.mapper.SealChannelMapper;
import com.credithc.signature.common.mapper.SealInfoMapper;
import com.credithc.signature.common.po.FddConfig;
import com.credithc.signature.common.po.FddSealInfo;
import com.credithc.signature.common.po.SealChannel;
import com.credithc.signature.common.po.SealInfo;
import com.credithc.signature.common.po.Template;
import com.credithc.signature.common.ro.manager.TemplateRo;
import com.credithc.signature.common.service.ChannelService;
import com.credithc.signature.common.service.SealInfoService;
import com.credithc.signature.common.utils.ManagerBeanUtil;
import com.credithc.signature.common.vo.manager.DictionaryVo;
import com.credithc.signature.common.vo.manager.TemplateVo;
import com.credithc.signature.manager.client.AuthClient;
import com.credithc.signature.manager.ro.TokenRo;
import com.credithc.signature.manager.service.AuthorizationService;
import com.credithc.signature.manager.service.SealChannelService;
import com.credithc.signature.manager.service.TemplateMService;
import com.credithc.signature.common.utils.FddConfigMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.websocket.server.PathParam;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
 * 描 述: 模板记录Controller<br/>
 * 作 者: JingBo Hu<br/>
 * 创 建：2019/5/24 16:55<br/>
 * 版 本：v1.0.0<br>
 */
@RestController
@RequestMapping("/manager/scs/v2")
@Slf4j
public class TemplateController {

    private static final Semaphore SEMAPHORE = new Semaphore(1);

    @Autowired
    MessageFactory messageFactory;

    @Autowired
    TemplateMService templateService;

    @Autowired
    HttpServletResponse response;

    @Autowired
    ChannelService channelService;

    @Autowired
    AuthorizationService authorizationService;

    @Autowired
    AuthClient authClient;

    @Autowired
    SealInfoMapper sealInfoMapper;

    @Autowired
    FddSealInfoMapper fddSealInfoMapper;

    @Autowired
    SealChannelMapper sealChannelMapper;

    @Autowired
    SealChannelService sealChannelService;

    @Autowired
    SealInfoService sealInfoService;


    /**
     * 查询所有
     *
     * @param templateRo
     * @return
     */
    @PostMapping("/template/list")
    public Message queryAll(@RequestHeader("token") String token, @RequestBody TemplateRo templateRo, HttpServletRequest request) {
        try {
            TemplateRo newTemplateRo = null;
            try {
                newTemplateRo = authorizationService.authTemplate(templateRo, token, request);
            } catch (BsException e) {
                return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, e.getMessage());
            }
            PageInfo<TemplateVo> pageInfo = templateService.queryAll(newTemplateRo);
            Map<String, PageInfo<TemplateVo>> map = new HashMap<>(16);
            map.put("pageInfo", pageInfo);
            return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
        } catch (Exception e) {
            log.error("获取授权时发生异常", e);
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, "获取授权时发生异常");
        }
    }

    /**
     * 查询单条
     *
     * @param id
     * @return
     */
    @GetMapping("/template/one/{id}")
    public Message queryOne(@PathVariable Long id) {
        TemplateVo templateVo = templateService.queryOne(id);
        Map<String, Object> map = new HashMap<>(16);
        map.put("vo", templateVo);
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
    }

    /**
     * 导出文件
     *
     * @param ids
     */
    @GetMapping("/template/export/{ids}")
    public void export(@PathVariable String ids) {
        templateService.export(ids, response, Template.class.getSimpleName());
    }

    /**
     * 上传文件
     *
     * @param file
     */
    @PostMapping("/template/upload")
    public Message upload(@RequestParam("file") MultipartFile file) {
        Integer templateExtId = templateService.uploadext(file);
        if (templateExtId == -1) {
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, "上传文件太大，超出限制范围");
        }
        Map<String, Object> map = new HashMap<>(16);
        map.put("templateExtId", templateExtId);
        map.put("fileName", file.getOriginalFilename());
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
    }

    /**
     * 新增
     *
     * @param templateRo
     * @return
     */
    @PostMapping("/template/save")
    public Message save(@RequestBody @Valid TemplateRo templateRo, HttpServletRequest request) {
        try {
            SEMAPHORE.acquire();
            Template template = templateService.selectByTemplateNo(templateRo.getTemplateNo());
            if (template != null) {
                return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, "改模板编号已存在！");
            }
            templateService.saveTemplateExt(templateRo, request);
            return messageFactory.getInstance(CoreCodes.CORE_SUCCESS);
        } catch (Exception e) {
            log.info("保存模板发生异常", e);
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, e.getMessage());
        } finally {
            SEMAPHORE.release();
        }
    }

    /**
     * 获取模板编号前缀
     *
     * @param templateRo
     * @return
     */
    @GetMapping("/template/queryTemplatePrefix")
    public Message getTemplateNoPrefix(@PathParam("productCode") String productCode, TemplateRo templateRo, HttpServletRequest request) {
        try {
            templateRo.setChannelNo(productCode);
            String templateNoPrefix = templateService.getTemplateNoPrefix(templateRo, request);
            Map<String, Object> map = new HashMap<>(16);
            map.put("templateNoPrefix", templateNoPrefix);
            return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
        } catch (Exception e) {
            log.info("获取模板编号前缀发生异常", e);
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, e.getMessage());
        }
    }

    /**
     * 运营后台新增模板
     *
     * @param templateRo
     * @return
     */
    @PostMapping("/template/save/ext")
    public Message saveExt(@RequestBody @Valid TemplateRo templateRo) {
        try {
            SEMAPHORE.acquire();
            Template template = templateService.selectByTemplateNo(templateRo.getTemplateNo());
            if (template != null) {
                return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, "该模板编号已存在！");
            }
            String s = templateService.saveTemplateExt1(templateRo);
            if (s == null) {
                return messageFactory.getInstance(CoreCodes.CORE_SUCCESS);
            } else {
                return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, s);
            }
        } catch (Exception e) {
            log.info("保存模板发生异常", e);
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, e.getMessage());
        } finally {
            SEMAPHORE.release();
        }
    }

    /**
     * 修改
     *
     * @param templateRo
     * @return
     */
    @PostMapping("/template/update")
    public Message update(@RequestHeader("token") String token, HttpServletRequest request, @RequestBody TemplateRo templateRo) {
        try {
            TokenRo authData = authorizationService.getAuthData(token, request);
            if (authData != null) {
                templateRo.setOperatorId(authData.getEhrId());
                templateRo.setOperatorName(authData.getUserName());
            }
            String msg = templateService.updateTemplateExt(templateRo);
            if (StringUtils.isBlank(msg)) {
                return messageFactory.getInstance(CoreCodes.CORE_SUCCESS);
            }
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, msg);
        } catch (Exception e) {
            log.error("获取授权时发生异常", e);
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, "获取授权时发生异常");
        }
    }


    /**
     * 修改审批流
     *
     * @param templateRo
     * @return
     */
    @PostMapping("/template/approval/update")
    public Message approvalUpdate(@RequestHeader("token") String token, HttpServletRequest request, @RequestBody TemplateRo templateRo) {
        try {
            TokenRo authData = authorizationService.getOperateAuthData(token, request);
            if (authData != null) {
                templateRo.setOperatorId(authData.getEhrId());
                templateRo.setOperatorName(authData.getUserName());
            }
            Message message = templateService.approvalUpdate(templateRo);
            if (message != null) {
                return messageFactory.getInstance(message.getCode(), message.getMsg());
            }
            return messageFactory.getInstance(CoreCodes.CORE_SUCCESS);
        } catch (Exception e) {
            log.error("获取授权时发生异常", e);
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, "获取授权时发生异常");
        }
    }

    /**
     * 修改模板状态
     *
     * @param templateRo
     * @return
     */
    @PostMapping("/template/updateSts")
    public Message updateSts(@RequestHeader("token") String token, HttpServletRequest request, @RequestBody TemplateRo templateRo) {
        try {
            TokenRo authData = authorizationService.getAuthData(token, request);
            if (authData != null) {
                templateRo.setOperatorId(authData.getEhrId());
                templateRo.setOperatorName(authData.getUserName());
            }
            templateService.updateTemplateSts(templateRo);
            return messageFactory.getInstance(CoreCodes.CORE_SUCCESS);
        } catch (Exception e) {
            log.error("获取授权时发生异常", e);
            return messageFactory.getInstance(CoreCodes.CORE_SYS_ERROR, "获取授权时发生异常");
        }
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @GetMapping("/template/remove/{id}")
    public Message remove(@PathVariable Long id) {
        templateService.remove(id);
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS);
    }

    /**
     * 查询签章类型
     *
     * @return
     */
    @PostMapping("/template/sealType/list")
    public Message querySealTypes() {
        List<DictionaryVo> vos = templateService.querySealTypes();
        Map<String, Object> map = new HashMap<>(16);
        map.put("list", vos);
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
    }

    /**
     * 查询公章规则号
     *
     * @return
     */
    @PostMapping("/template/officialSealId/list")
    public Message queryOfficialSeal(HttpServletRequest request) {
        List<DictionaryVo> vos = new ArrayList<>();
        Message<TokenRo> tokenRo = authClient.getUserInfoByToken(request.getHeader("token"));
        log.info("数据权限查询结果:" + tokenRo.toString());
        if (tokenRo.getData() != null) {
            TokenRo data = tokenRo.getData();
            String productCode = data.getProductCode();
            Example example = new Example(SealChannel.class);
            example.createCriteria().andEqualTo("channelNo", productCode);
            List<SealChannel> sealChannels = sealChannelMapper.selectByExample(example);
            Set<String> set = new HashSet<>();
            for (SealChannel sealChannel : sealChannels) {
                set.add(sealChannel.getSealCode());
            }
            FddConfig fddConfig = FddConfigMap.getConfig().get(productCode);
            if (fddConfig == null) {
                set.forEach(s -> {
                    SealInfo sealInfo = sealInfoMapper.selectBySealCode(s);
                    if (sealInfo != null) {
                        DictionaryVo vo = new DictionaryVo();
                        vo.setCode(s);
                        vo.setName(sealInfo.getKeyWords());
                        vos.add(vo);
                    }
                });
            } else {
                set.forEach(s -> {
                    FddSealInfo sealInfoParams = new FddSealInfo();
                    sealInfoParams.setAppId(fddConfig.getAppId());
                    sealInfoParams.setSealCode(s);
                    Map<String, Object> params = ManagerBeanUtil.buildQueryParams(sealInfoParams);
                    FddSealInfo fddSealInfo = fddSealInfoMapper.selectOneByExample(params.get(ManagerConstant.EXAMPLE));
                    if (fddSealInfo != null) {
                        DictionaryVo vo = new DictionaryVo();
                        vo.setCode(s);
                        vo.setName(fddSealInfo.getKeyWords());
                        vos.add(vo);
                    }
                });
            }
        }
        Map<String, Object> map = new HashMap<>(16);
        map.put("list", vos);
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
    }


    /**
     * 查询公章规则号
     *
     * @return
     */
    @PostMapping("/template/officialSealId/list/pro")
    public Message queryOfficialSealByChannelNo(@PathParam("productCode") String productCode) {
        List<DictionaryVo> vos = new ArrayList<>();
        Example example = new Example(SealChannel.class);
        if (StringUtils.isNotBlank(productCode)) {
            example.createCriteria().andEqualTo("channelNo", productCode);
        }
        List<SealChannel> sealChannels = sealChannelMapper.selectByExample(example);
        Set<String> set = new HashSet<>();
        for (SealChannel sealChannel : sealChannels) {
            set.add(sealChannel.getSealCode());
        }
        FddConfig fddConfig = FddConfigMap.getConfig().get(productCode);
        if (fddConfig == null) {
            set.forEach(s -> {
                SealInfo sealInfo = sealInfoMapper.selectBySealCode(s);
                if (sealInfo != null) {
                    DictionaryVo vo = new DictionaryVo();
                    vo.setCode(s);
                    vo.setName(sealInfo.getKeyWords());
                    vos.add(vo);
                }
            });
        } else {
            set.forEach(s -> {
                FddSealInfo sealInfoParams = new FddSealInfo();
                sealInfoParams.setAppId(fddConfig.getAppId());
                sealInfoParams.setSealCode(s);
                Map<String, Object> params = ManagerBeanUtil.buildQueryParams(sealInfoParams);
                FddSealInfo fddSealInfo = fddSealInfoMapper.selectOneByExample(params.get(ManagerConstant.EXAMPLE));
                if (fddSealInfo != null) {
                    DictionaryVo vo = new DictionaryVo();
                    vo.setCode(s);
                    vo.setName(fddSealInfo.getKeyWords());
                    vos.add(vo);
                }
            });
        }
        Map<String, Object> map = new HashMap<>(16);
        map.put("list", vos);
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
    }

    /**
     * 查询公章规则号--根据模板ID
     *
     * @return
     */
    @GetMapping("/template/officialSealId/{id}")
    public Message queryOfficialSealById(@PathVariable String id) {
        List<DictionaryVo> vos = templateService.queryOfficialSealById(id);
        Map<String, Object> map = new HashMap<>(16);
        map.put("list", vos);
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
    }

    /**
     * 查询审核状态
     *
     * @return
     */
    @PostMapping("/template/auditStatus/list")
    public Message queryAuditStatus() {
        List<DictionaryVo> vos = templateService.queryAuditStatus();
        Map<String, Object> map = new HashMap<>(16);
        map.put("list", vos);
        return messageFactory.getInstance(CoreCodes.CORE_SUCCESS, map);
    }

}
